from psd_tools import PSDImage
import json
import sys
import os
import hashlib

def CalcMD5(filepath):
    with open(filepath,'rb') as f:
        md5obj = hashlib.md5()
        md5obj.update(f.read())
        hash_code = md5obj.hexdigest()
        return hash_code

def getFilePath(list,path):
    fileList=os.listdir(path)

    for file in fileList:

        dirName = os.path.join(path, file)

        suffix = os.path.splitext(dirName)[1]

        if os.path.isdir(dirName):
            getFilePath(list,dirName)
            continue

        if suffix == '.png':
            if dirName[0] != "~":
                list.append(dirName)

    return list

class PsdImport:
    def __init__(self, config):
        self.config = config
        self.initPublicRes()

    def initPublicRes(self):
        self.public_res_map = {}
        
        for conf in self.config["template"]:
            file_list = []
            getFilePath(file_list,conf["path"])

            special = {}
            if "special" in conf.keys():
                special = conf["special"]

            for img in file_list:
                hash = CalcMD5(img)
                name = os.path.basename(img)
                trans = False
                if name in special.keys():
                    name = special[name]
                    trans = True
                self.public_res_map[hash] = {
                    "name" : name,
                    "hash" : hash,
                    "plist": conf["plist"],
                    "trans" : trans
                }

    def gen(self,psd_config):
        if not os.path.exists(psd_config["plist"]):
            os.mkdir(psd_config["plist"])

        psd_conf = {}
        psd_conf["save_name"] = os.path.basename(psd_config["plist"])
        psd_conf["save_path"] = psd_config["plist"]

        psd = PSDImage.open(psd_config["psd"])

        Output = {}
        Output["children"] = []
        Output["width"] = psd.width 
        Output["height"] = psd.height
        Output["root"] = True
        # Output["pos"] = [0,0]

        psd_conf["width"] = psd.width
        psd_conf["height"] = psd.height

        self.pairsLayer(Output,psd,psd_conf)

        with open(psd_config["json"], 'w', encoding='utf-8') as json_file:
            json.dump(Output, json_file,indent = 4,separators=(", ", ": "), sort_keys=True,ensure_ascii=False)

    def pairsLayer(self,Output,psd,conf):
        for layer in psd:
            if layer.visible:
                child = {}

                child["bottom"] = layer.bottom
                child["ps_size"] = layer.size
                
                child["pos"] = [layer.left - psd.left,(conf["height"] - layer.bottom) - (conf["height"] - psd.bottom)]
                # child["id"] = layer.name

                if layer.kind == "smartobject" or layer.kind == "shape" or layer.kind == "pixel":
                    child["type"] = "sprite"
                    child["res"] = layer.name
                    child["plist"] = conf["save_name"]
                    path = '%s.png' % (conf["save_path"] + "/" + layer.name)
                    # saveImage(layer,path)
                    layer_image = layer.composite()
                    layer_image.save(path)
                    hash_value = CalcMD5(path)
                    if hash_value in self.public_res_map.keys():
                        child["plist"] = self.public_res_map[hash_value]["plist"]
                        if self.public_res_map[hash_value]["trans"]:
                            child["res_real"] = self.public_res_map[hash_value]["name"].replace(".png","")
                        else:
                            child["res"] = self.public_res_map[hash_value]["name"].replace(".png","")
                        os.remove(path)
                elif layer.is_group():
                    child["type"] = "node"
                    child["children"] = []
                    # child["pos"][1] -= layer.size[1]
                    self.pairsLayer(child,layer,conf)
                elif layer.kind == "type":
                    child["type"] = "label"
                    child["text"] = layer.text
                    StyleSheetData = layer.engine_dict['StyleRun']['RunArray'][0]['StyleSheet']['StyleSheetData']
                    fontSize = StyleSheetData['FontSize']
                    child["size"] = int(fontSize)
                    colorValue = StyleSheetData["FillColor"]["Values"]
                    child["color"] = [int(colorValue[1]*255),int(colorValue[2]*255),int(colorValue[3]*255)]
                    child["align"] = ["center",child["pos"][0] + layer.size[0]/2,child["pos"][1] + layer.size[1]/2]
                else:
                    print(layer.kind)
                    continue

                Output["children"].append(child)

def main():
    with open("config.json" , "r", encoding="utf-8") as f:
        config = json.load(f)

    gen_psd = config["gen"]

    psd_import = PsdImport(config)

    for i in range(len(gen_psd)):
        psd_import.gen(gen_psd[i])

if __name__ == "__main__":
    main()